package com.nokia.example3dgame;

import javax.microedition.m3g.*;

public class AlienModel {

	static {
		Image2D enemyIm = loadImage2D("/game/alien.png");
		Image2D frozenEnemyIm = loadImage2D("/game/alien_frozen.png");
		vb = makeGeometry();
		ib = new TriangleStripArray(0, getStripLengths());
		app = makeAppearance(enemyIm);
		frozenApp = makeFrozenAppearance(frozenEnemyIm);
	}

	private static VertexBuffer vb;

	private static IndexBuffer ib;

	private static Appearance app;

	private static Appearance frozenApp;

	private Mesh model;

	public AlienModel(float xCoord, float zCoord) {
		model = new Mesh(vb, ib, app);
		model.setTranslation(xCoord + 0.25f, 0.25f, zCoord + 0.25f);
		model.scale(0.5f, 0.5f, 0.5f);
		model.setPickingEnable(true); // so can fire a pick ray at it

	}

	public Mesh getModel() {
		return model;
	}

	public static Appearance getFrozenAppearance() {
		return frozenApp;
	}

	// ------------------- model creation -----------------------------

	private static VertexBuffer makeGeometry() {
		//		 create vertices
		short[] verts = getVerts();
		VertexArray va = new VertexArray(verts.length / 3, 3, 2);
		va.set(0, verts.length / 3, verts);

		// create normals
		byte[] norms = getNormals();
		VertexArray normArray = new VertexArray(norms.length / 3, 3, 1);
		normArray.set(0, norms.length / 3, norms);

		// create texture coordinates
		short[] tcs = getTexCoordsRev();
		VertexArray texArray = new VertexArray(tcs.length / 2, 2, 2);
		texArray.set(0, tcs.length / 2, tcs);

		float[] pbias = { (1.0f / 255.0f), (1.0f / 255.0f), (1.0f / 255.0f) };

		VertexBuffer vb = new VertexBuffer();
		vb.setPositions(va, (2.0f / 255.0f), pbias); // scale, bias
		vb.setNormals(normArray);
		vb.setTexCoords(0, texArray, (1.0f / 255.0f), null);

		return vb;

	} // end of makeGeometry()

	private static short[] getTexCoordsRev() {
		short[] tcs = getTexCoords();
		// t' = 255 - t (will later be scaled from 255 to 1)
		for (int i = 1; i < tcs.length; i = i + 2)
			tcs[i] = (short) (255 - tcs[i]);

		return tcs;
	} // end of getTexCoordsRev()

	private static Appearance makeAppearance(Image2D image2D)
	// the appearance is a mix of material and texture
	{
		Appearance app = new Appearance();
		app.setMaterial(setMatColours());

		if (image2D != null) {
			// create the Texture2D and enable mipmapping
			Texture2D tex = new Texture2D(image2D);
			tex
					.setFiltering(Texture2D.FILTER_NEAREST,
							Texture2D.FILTER_NEAREST);
			tex.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP);
			tex.setBlending(Texture2D.FUNC_MODULATE); // mix material and
			// texture
			app.setTexture(0, tex);
		}
		return app;
	} // end of makeAppearance()

	private static Appearance makeFrozenAppearance(Image2D image2D)
	// the appearance is a mix of material and texture
	{
		Appearance app = new Appearance();

		if (image2D != null) {
			// create the Texture2D and enable mipmapping
			Texture2D tex = new Texture2D(image2D);
			tex
					.setFiltering(Texture2D.FILTER_NEAREST,
							Texture2D.FILTER_NEAREST);
			tex.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP);
			tex.setBlending(Texture2D.FUNC_MODULATE); // mix material and
			// texture
			app.setTexture(0, tex);
		}
		return app;
	} // end of makeFrozenAppearance()

	// ------------------ model data ------------------------

	private static short[] getVerts()
	// return an array holding Verts [870 values / 3 = 290 points]
	{
		short[] vals = { -72, -38, -84, -72, -24, -85, -71, 3, -79, -79, 6,
				-85, -71, 3, -79, -54, -1, -78, -74, -6, -78, -54, -1, -78,
				-69, 2, -72, -30, -42, -87, -69, 2, -72, -70, 10, -65, -58,
				-25, -67, -70, 10, -65, -62, -54, -76, -67, -17, -78, -62, -54,
				-76, -72, -16, -77, -72, -32, -86, -72, -16, -77, -89, -49,
				-76, -70, 8, -68, -89, -49, -76, -82, 6, -68, -77, 4, -64, -82,
				6, -68, -79, 5, -72, -115, -38, -86, -79, 5, -72, -108, -37,
				-95, -74, 12, -78, -108, -37, -95, -71, 2, -79, -108, -37, -95,
				-74, 6, -85, -108, -37, -95, -101, -2, -75, -111, -8, -86,
				-101, -2, -75, -84, 21, -76, -84, 21, -75, -84, 21, -76, -87,
				54, -94, -84, 21, -76, -107, 53, -67, -84, 21, -76, -128, 56,
				-64, -85, 22, -74, -128, 56, -64, -81, 15, -69, -121, 81, -39,
				-81, 15, -69, -110, 110, -26, -68, 30, -45, -110, 110, -26,
				-71, 37, -19, -80, 95, -5, -71, 37, -19, -28, 84, -11, -37, 37,
				-33, -28, 84, -11, -61, 22, -70, -29, 95, -20, -61, 22, -70,
				-35, 96, -79, -56, 19, -74, -35, 96, -79, -57, 19, -76, -27,
				51, -85, -57, 19, -76, -27, 53, -95, -57, 19, -76, -49, 22,
				-76, -57, 19, -76, -70, 15, -77, -57, 19, -76, -28, -26, -72,
				-57, 19, -76, -28, -27, -67, -56, 19, -74, -28, -27, -67, -61,
				22, -70, -70, 19, -71, -61, 22, -70, -67, 15, -68, -37, 37,
				-33, -67, 15, -68, -71, 37, -19, -72, 16, -69, -71, 37, -19,
				-78, 14, -74, -68, 30, -45, -78, 14, -74, -81, 15, -69, -71,
				18, -71, -81, 15, -69, -118, -22, -72, -85, 22, -74, -118, -22,
				-72, -84, 21, -76, -118, -22, -72, -111, -8, -86, -118, -22,
				-72, -108, -37, -95, -118, -22, -72, -115, -38, -86, -118, -22,
				-72, -82, 6, -68, -71, 18, -71, -82, 6, -68, -78, 14, -74, -70,
				8, -68, -78, 14, -74, -72, -16, -77, -72, 16, -69, -72, -16,
				-77, -67, 15, -68, -67, -17, -78, -67, 15, -68, -70, 10, -65,
				-70, 19, -71, -70, 10, -65, -28, -27, -67, -30, -42, -87, -28,
				-27, -67, -54, -1, -78, -28, -26, -72, -54, -1, -78, -70, 15,
				-77, -79, 6, -85, -70, 15, -77, -72, -24, -85, -70, 15, -77,
				-71, -1, -82, -70, 15, -77, -72, 20, -79, -49, 22, -76, -72,
				20, -79, -27, 53, -95, -72, 58, -95, -27, 53, -95, -71, 100,
				-87, -27, 53, -95, -57, 100, -92, -27, 53, -95, -33, 97, -93,
				-27, 51, -85, -33, 97, -93, -35, 96, -79, -30, 108, -92, -35,
				96, -79, -50, 123, -57, -29, 95, -20, -50, 123, -57, -28, 84,
				-11, -55, 124, -41, -28, 84, -11, -72, 123, -34, -80, 95, -5,
				-72, 123, -34, -110, 110, -26, -110, 125, -44, -110, 110, -26,
				-100, 127, -54, -121, 81, -39, -100, 127, -54, -128, 56, -64,
				-99, 117, -74, -128, 56, -64, -111, 115, -74, -107, 53, -67,
				-111, 115, -74, -87, 54, -94, -80, 106, -85, -87, 54, -94, -71,
				106, -87, -87, 54, -94, -72, 58, -99, -87, 54, -94, -72, 19,
				-77, -84, 21, -75, -72, 19, -77, -101, -2, -75, -71, -3, -86,
				-101, -2, -75, -72, -24, -85, -74, 6, -85, -72, -24, -85, -71,
				2, -79, -72, -38, -84, -71, 2, -79, -72, -34, -84, -71, 2, -79,
				-89, -70, -103, -71, 2, -79, -101, -70, -90, -74, 12, -78,
				-101, -70, -90, -79, 5, -72, -109, -70, -72, -79, 5, -72, -116,
				-69, -67, -77, 4, -64, -116, -69, -67, -89, -49, -76, -110,
				-69, -61, -89, -49, -76, -102, -69, -59, -89, -49, -76, -85,
				-70, -71, -89, -49, -76, -72, -32, -86, -72, -32, -86, -72,
				-32, -86, -62, -54, -76, -52, -68, -58, -62, -54, -76, -39,
				-69, -58, -62, -54, -76, -30, -71, -53, -62, -54, -76, -27,
				-71, -60, -58, -25, -67, -27, -71, -60, -69, 2, -72, -33, -71,
				-86, -69, 2, -72, -42, -70, -90, -74, -6, -78, -42, -70, -90,
				-71, 3, -79, -55, -70, -103, -71, 3, -79, -72, -34, -84, -72,
				-38, -84, -71, 100, -87, -80, 106, -85, -71, 125, -74, -111,
				115, -74, -71, 125, -74, -111, 115, -74, -71, 125, -74, -109,
				125, -44, -71, 125, -74, -83, 125, -35, -71, 125, -74, -70,
				121, -34, -71, 125, -74, -54, 125, -37, -71, 125, -74, -50,
				123, -57, -71, 125, -74, -36, 94, -84, -71, 125, -74, -34, 94,
				-92, -71, 125, -74, -57, 101, -92, -71, 100, -87, -72, -70,
				-108, -55, -70, -103, -72, -70, -72, -42, -70, -90, -72, -70,
				-72, -33, -70, -72, -72, -70, -72, -27, -70, -46, -72, -70,
				-72, -30, -70, -39, -72, -70, -72, -39, -70, -35, -72, -70,
				-72, -56, -70, -36, -72, -70, -72, -72, -70, -37, -72, -70,
				-72, -86, -70, -36, -72, -70, -72, -102, -70, -38, -72, -70,
				-72, -110, -70, -40, -72, -70, -72, -116, -70, -45, -72, -70,
				-72, -109, -70, -72, -72, -70, -72, -101, -70, -90, -72, -70,
				-72, -89, -70, -103, -72, -70, -72, -72, -70, -108 };
		return vals;
	} // end of getVerts()

	private static byte[] getNormals()
	// return an array holding Normals [870 values / 3 = 290 points]
	{
		byte[] vals = { 64, -14, 110, 124, 2, -33, 66, -33, -105, 14, -63,
				-111, 66, -33, -105, 30, -36, -119, 116, -52, -16, 30, -36,
				-119, 117, 28, -43, -81, -94, -31, 117, 28, -43, -98, -59, 58,
				4, 9, 127, -98, -59, 58, -38, 46, 113, -94, -11, 86, -38, 46,
				113, 17, -35, 122, -17, -71, 105, 17, -35, 122, 68, 11, 108,
				71, 18, 105, 68, 11, 108, 45, -71, 96, -15, -117, 49, 45, -71,
				96, -89, -90, -19, 48, -96, 69, -89, -90, -19, 32, -39, -118,
				-61, -65, -91, 32, -39, -118, -41, 0, -121, 32, -39, -118,
				-125, 28, -7, 32, -39, -118, 44, 5, -120, -29, 38, -119, 44, 5,
				-120, -56, -60, -98, 100, -48, -64, -56, -60, -98, -47, -10,
				-119, -56, -60, -98, -65, -15, -110, -56, -60, -98, -120, -33,
				-31, -120, -42, -15, -120, -33, -31, -53, -59, 100, -108, -12,
				68, -53, -59, 100, -99, -13, 80, -103, -60, 46, -99, -13, 80,
				-44, -82, 88, -18, 36, 122, -44, -82, 88, 79, 49, 88, 92, -86,
				22, 79, 49, 88, 125, -28, 8, 124, 32, 12, 125, -28, 8, 124, -3,
				33, 125, 23, 15, 124, -3, 33, 127, -16, -11, 121, -19, 36, 127,
				-16, -11, 36, -26, -120, 127, -16, -11, 36, -101, -69, 127,
				-16, -11, 92, -7, -89, 127, -16, -11, 84, 45, -86, 127, -16,
				-11, 90, 43, 80, 125, 23, 15, 90, 43, 80, 125, -28, 8, 100,
				-80, 6, 125, -28, 8, 2, -128, 6, 92, -86, 22, 2, -128, 6, -44,
				-82, 88, -36, -81, 92, -44, -82, 88, -11, -36, 123, -103, -60,
				46, -11, -36, 123, -53, -59, 100, -11, 94, 86, -53, -59, 100,
				-108, 48, 49, -120, -42, -15, -108, 48, 49, -56, -60, -98,
				-108, 48, 49, -29, 38, -119, -108, 48, 49, 32, -39, -118, -108,
				48, 49, 48, -96, 69, -108, 48, 49, 45, -71, 96, -11, 94, 86,
				45, -71, 96, -11, -36, 123, 71, 18, 105, -11, -36, 123, 17,
				-35, 122, -36, -81, 92, 17, -35, 122, 2, -128, 6, -94, -11, 86,
				2, -128, 6, -98, -59, 58, 100, -80, 6, -98, -59, 58, 90, 43,
				80, -81, -94, -31, 90, 43, 80, 30, -36, -119, 84, 45, -86, 30,
				-36, -119, 92, -7, -89, 14, -63, -111, 92, -7, -89, 124, 2,
				-33, 92, -7, -89, 114, 7, -57, 92, -7, -89, 41, -45, -113, 36,
				-101, -69, 41, -45, -113, 36, -26, -120, -3, -13, -127, 36,
				-26, -120, -22, 2, -126, 36, -26, -120, -25, -7, -125, 36, -26,
				-120, 123, 4, -34, 121, -19, 36, 123, 4, -34, 124, -3, 33, 123,
				-5, 35, 124, -3, 33, 86, 80, 51, 124, 32, 12, 86, 80, 51, 79,
				49, 88, 68, 91, 60, 79, 49, 88, 7, 93, 88, -18, 36, 122, 7, 93,
				88, -99, -13, 80, -127, 12, 10, -99, -13, 80, -120, 16, -42,
				-108, -12, 68, -120, 16, -42, -120, -33, -31, -91, 55, 71,
				-120, -33, -31, -82, 9, -98, -65, -15, -110, -82, 9, -98, -47,
				-10, -119, -29, 25, -122, -47, -10, -119, -33, 27, -121, -47,
				-10, -119, -34, -17, -122, -47, -10, -119, -25, -19, -124, 100,
				-48, -64, -25, -19, -124, 44, 5, -120, -43, 19, -119, 44, 5,
				-120, -124, -6, 32, -125, 28, -7, -124, -6, 32, -41, 0, -121,
				-60, 14, -112, -41, 0, -121, 85, 10, -95, -41, 0, -121, 1, 40,
				-122, -41, 0, -121, -87, 43, -83, -61, -65, -91, -87, 43, -83,
				-89, -90, -19, -93, 38, -80, -89, -90, -19, -89, 78, 49, -15,
				-117, 49, -89, 78, 49, 68, 11, 108, -38, 97, 74, 68, 11, 108,
				29, 71, 103, 68, 11, 108, 54, 37, 110, 68, 11, 108, 102, 39,
				66, -17, -71, 105, 102, 39, 66, -38, 46, 113, 78, 96, 34, -38,
				46, 113, -24, 83, 95, -38, 46, 113, 4, 107, 70, -38, 46, 113,
				47, 76, 92, 4, 9, 127, 47, 76, 92, 117, 28, -43, 88, 57, -73,
				117, 28, -43, 91, 54, -72, 116, -52, -16, 91, 54, -72, 66, -33,
				-105, 6, 41, -121, 66, -33, -105, -128, 5, -2, 64, -14, 110,
				-11, 62, -112, 0, 68, -109, 12, 121, -40, -29, 124, -11, 12,
				121, -40, -29, 121, 29, 12, 121, -40, -12, 126, -20, 12, 121,
				-40, 18, 127, 5, 12, 121, -40, 3, 127, 11, 12, 121, -40, -4,
				127, 0, 12, 121, -40, 41, 114, -41, 12, 121, -40, 81, 98, -18,
				12, 121, -40, 66, 104, -36, 12, 121, -40, -7, 74, -104, -11,
				62, -112, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0,
				-128, 0, 0, -128, 0, 0, -128, 0 };
		return vals;
	} // end of getNormals()

	private static short[] getTexCoords()
	// return an array holding TexCoords [580 values / 2 = 290 points]
	{
		short[] vals = { 0, 43, 0, 85, 21, 43, 21, 85, 21, 43, 43, 85, 43, 43,
				43, 85, 64, 43, 64, 85, 64, 43, 85, 85, 85, 43, 85, 85, 107,
				43, 107, 85, 107, 43, 128, 85, 128, 43, 128, 85, 149, 43, 149,
				85, 149, 43, 171, 85, 171, 43, 171, 85, 192, 43, 192, 85, 192,
				43, 213, 85, 213, 43, 213, 85, 235, 43, 213, 85, 235, 85, 213,
				85, 235, 128, 213, 128, 235, 128, 213, 171, 235, 171, 213, 171,
				235, 213, 213, 171, 213, 213, 213, 171, 192, 213, 192, 171,
				192, 213, 171, 171, 171, 213, 171, 171, 149, 213, 149, 171,
				149, 213, 128, 171, 128, 213, 128, 171, 107, 213, 107, 171,
				107, 213, 85, 171, 85, 213, 85, 171, 64, 213, 64, 171, 64, 213,
				43, 171, 43, 213, 43, 171, 21, 213, 43, 171, 21, 171, 43, 171,
				21, 128, 43, 171, 43, 128, 43, 171, 64, 128, 64, 171, 64, 128,
				85, 171, 85, 128, 85, 171, 107, 128, 107, 171, 107, 128, 128,
				171, 128, 128, 128, 171, 149, 128, 149, 171, 149, 128, 171,
				171, 171, 128, 171, 171, 192, 128, 192, 171, 192, 128, 213,
				171, 192, 128, 213, 128, 192, 128, 213, 85, 192, 128, 192, 85,
				192, 128, 171, 85, 171, 128, 171, 85, 149, 128, 149, 85, 149,
				128, 128, 85, 128, 128, 128, 85, 107, 128, 107, 85, 107, 128,
				85, 85, 85, 128, 85, 85, 64, 128, 64, 85, 64, 128, 43, 85, 43,
				128, 43, 85, 21, 128, 21, 85, 21, 128, 0, 85, 21, 128, 0, 128,
				21, 128, 0, 171, 21, 171, 0, 171, 21, 213, 0, 213, 21, 213, 0,
				255, 21, 213, 21, 255, 21, 213, 43, 255, 43, 213, 43, 255, 64,
				213, 64, 255, 64, 213, 85, 255, 85, 213, 85, 255, 107, 213,
				107, 255, 107, 213, 128, 255, 128, 213, 128, 255, 149, 213,
				149, 255, 149, 213, 171, 255, 171, 213, 171, 255, 192, 213,
				192, 255, 192, 213, 213, 255, 213, 213, 213, 255, 235, 213,
				235, 255, 235, 213, 255, 255, 235, 213, 255, 213, 235, 213,
				255, 171, 235, 171, 255, 171, 235, 128, 255, 128, 235, 128,
				255, 85, 235, 85, 255, 85, 235, 43, 255, 43, 235, 43, 255, 0,
				235, 43, 235, 0, 235, 43, 213, 0, 213, 43, 213, 0, 192, 43,
				192, 0, 192, 43, 171, 0, 171, 43, 171, 0, 149, 43, 165, 0, 149,
				43, 160, 0, 149, 43, 149, 0, 149, 43, 128, 0, 128, 43, 128, 0,
				107, 43, 107, 0, 107, 43, 101, 0, 107, 43, 96, 0, 107, 43, 85,
				0, 85, 43, 85, 0, 64, 43, 64, 0, 64, 43, 43, 0, 43, 43, 43, 0,
				21, 43, 21, 0, 21, 43, 0, 0, 0, 43, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
				255, 0, 255, 0, 255, 0, 255 };
		return vals;
	} // end of getTexCoords()

	private static int[] getStripLengths()
	// return an array holding the lengths of each triangle strip
	{
		int[] lens = { 235, 23, 32 };
		return lens;
	} // end of getStripLengths()

	private static Material setMatColours()
	// set the material's colour and shininess values
	{
		Material mat = new Material();

		mat.setColor(Material.AMBIENT, 0x0003C1C1);
		mat.setColor(Material.EMISSIVE, 0x00000000);
		mat.setColor(Material.DIFFUSE, 0xFFE9B1E8);
		mat.setColor(Material.SPECULAR, 0x00000000);
		mat.setShininess(128.0f);

		return mat;
	} // end of setMatColours()

	private static Image2D loadImage2D(String fn) {
		Image2D im = null;
		try {
			im = (Image2D) Loader.load(fn)[0];
		} catch (Exception e) {
			System.out.println("Cannot make image from " + fn);
		}
		return im;
	}

}

